tree grammar BpslSinglePassTreeWalker;

options{
	tokenVocab=BpslLanguage;
	ASTLabelType=CommonTree;
}

@header{
	package patternmining.model.construction.bpsl;
	
	import java.util.Map;
	import java.util.HashMap;
	import patternmining.model.graph.bpsl.*;
}


specification	returns [BpslFormula formula]
			@init{
				formula = new BpslFormula();
				Map<String, BpslVariable> variables = new HashMap<String, BpslVariable>();
				String nameSpace;
			 }
			:	a=PATTERNNAME { nameSpace = $a.text; nameSpace = nameSpace.trim(); nameSpace = nameSpace.substring(1); }
				(
				^(CLASSDEF (a=ID
				{	
					if ( ! variables.containsKey($a.text) ) {
						//add variable to the symbol table
						BpslVariable variable = new BpslClass(nameSpace + "." + $a.text);
						variables.put($a.text, variable );
						//add term as vertex to the graph under construction
						formula.add( variable );	
					}
					else {
						// variable already used. treat errror
					}
				})+
				)
			|	

				^(TYPEDVARDEF (a=ID
				{
					if ( ! variables.containsKey($a.text) ) {
						//add variable to the symbol table
						BpslVariable variable = new BpslTypedVariable(nameSpace + "." + $a.text);
						variables.put($a.text, variable );
						//add term as vertex to the graph under construction
						formula.add( variable );	
					}
					else {
						// variable allready used. treat errror
					}	
				})+
				)
				
			|
	
				^(METHODDEF (a=ID
				{
					if ( ! variables.containsKey($a.text) ) {
						//add variable to the symbol table
						BpslVariable variable = new BpslMethod(nameSpace + "." + $a.text);
						variables.put($a.text, variable );
						//add term as vertex to the graph under construction
						formula.add( variable );	
					}
					else {
						// variable allready used. treat errror
					}	
				})+
				)
			)+
				
				( ^(c=PREDICATE a=ID b=ID)
				{ 
					BpslVariable argA, argB;
					//verify if ID a has been declared and get his type
					argA = variables.get($a.text);
					//verify if ID b has been declard and get his type
					argB = variables.get($b.text);
					//if both have been declared verify if predicate is defined for this domain
					if (argA != null && argB != null) {
						//if predicate is defined add adge to graph
						if ( BpslPredicate.acceptsArguments($c.text, argA, argB) ){
							//add atom as edge to the graph under construction
							formula.add( BpslPredicate.getPredicate($c.text, argA, argB) );
						}
						//else treat error
						else {
						} 
					
					}
					//else treat error
					else {
					}
						
				}
				)*
			;
